/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javacroft.facade;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javacroft.business.*;
import javacroft.dataccess.DataAccessFactory;

/**
 * Classe manager pour les étudiants
 * @author Fabien RETIF
 * @version 1.0
 */
public class EtudiantManager
{

   private List<Etudiant> lesEtudiants = null;
   private DataAccessFactory service = null;

   public EtudiantManager(DataAccessFactory daf)
   {
      service = daf;
      lesEtudiants = new ArrayList<Etudiant>();
   }

   /**
    * @return the lesEtudiants
    */
   public List<Etudiant> getLesEtudiants()
   {
      return lesEtudiants;
   }

   /**
    * @param lesEtudiants the lesEtudiants to set
    */
   public void setLesEtudiants(List<Etudiant> lesEtudiants)
   {
      this.lesEtudiants = lesEtudiants;
   }

   /**
    * Procédure de chargement des étudiants d'une année depuis la couche persistence
    * @param uneAnnee
    * @throws Exception : Exception venant des couches inférieures
    */
   public void chargerLesEtudiants(Annee uneAnnee) throws Exception
   {
      List<Map> lesDonnees = service.getLesEtudiantsAnnee(uneAnnee.getNom());
      List<Map> lesDonneesSemestreEtranger = null;
      int i = 0;
      Etudiant etudiantCourant = null;
      UE ueCourante = null;
      Semestre semestreCourant = null;
      String nomTemp = "", prenomTemp = "", codeSemestreTemp = "", estSemestreEtranger = "", nomUETemp = "", estAPDJ = "", nomECUETemp = "", noteECUETemp = "", estRattrapage = "";

      while (i < lesDonnees.size())
      {
         //********************** CREATION ETUDIANT ****************************
         nomTemp = lesDonnees.get(i).get("unNom").toString();
         prenomTemp = lesDonnees.get(i).get("unPrenom").toString();

         etudiantCourant = new Etudiant(lesDonnees.get(i).get("unNom").toString(), lesDonnees.get(i).get("unPrenom").toString(), uneAnnee, lesDonnees.get(i).get("scoreTOEIC").toString());

         //********************** POINTJURY ANNEE ****************************
         if (!lesDonnees.get(i).get("pointJuryAnnee").toString().startsWith("0"))
         {
            etudiantCourant.addPointJuryA(uneAnnee, Float.parseFloat(lesDonnees.get(i).get("pointJuryAnnee").toString()));
         }

         while (i < lesDonnees.size() && lesDonnees.get(i).get("unNom").toString().equalsIgnoreCase(nomTemp) && lesDonnees.get(i).get("unPrenom").toString().equalsIgnoreCase(prenomTemp))
         {
            codeSemestreTemp = lesDonnees.get(i).get("codeSemestre").toString();
            estSemestreEtranger = lesDonnees.get(i).get("estSemestreEtranger").toString();
            semestreCourant = uneAnnee.getLeSemestre(codeSemestreTemp);

            //********************** SEMESTRE ETRANGER ****************************
            if (estSemestreEtranger.equalsIgnoreCase("1"))
            {
               lesDonneesSemestreEtranger = service.getLesMoyennesEtranger(etudiantCourant.getNom(), etudiantCourant.getPrenom(), codeSemestreTemp);
               if (lesDonneesSemestreEtranger.size() > 0)
               {
                  etudiantCourant.ajouterSemestreEtranger(semestreCourant, Float.valueOf(lesDonneesSemestreEtranger.get(0).get("moyenneSemestre").toString()));
               }

            }

            //********************** POINTJURY SEMESTRE ****************************
            if (!lesDonnees.get(i).get("pointJurySemestre").toString().startsWith("0"))
            {
               etudiantCourant.addPointJuryS(semestreCourant, Float.parseFloat(lesDonnees.get(i).get("pointJurySemestre").toString()));
            }

            while (i < lesDonnees.size() && lesDonnees.get(i).get("unNom").toString().equalsIgnoreCase(nomTemp) && lesDonnees.get(i).get("unPrenom").toString().equalsIgnoreCase(prenomTemp) && lesDonnees.get(i).get("codeSemestre").toString().equalsIgnoreCase(codeSemestreTemp))
            {
               //********************** INSCRIPTION UE ****************************
               nomUETemp = lesDonnees.get(i).get("nomUE").toString();
               ueCourante = semestreCourant.getUE(nomUETemp);
               estAPDJ = lesDonnees.get(i).get("apdjUE").toString();

               etudiantCourant.ajouterUE(ueCourante);

               //********************** APDJ SUR UE ****************************
               if (estAPDJ.equalsIgnoreCase("1"))
               {
                  etudiantCourant.ajouterAPDJuE(ueCourante);
               }

               while (i < lesDonnees.size() && lesDonnees.get(i).get("unNom").toString().equalsIgnoreCase(nomTemp) && lesDonnees.get(i).get("unPrenom").toString().equalsIgnoreCase(prenomTemp) && lesDonnees.get(i).get("codeSemestre").toString().equalsIgnoreCase(codeSemestreTemp) && lesDonnees.get(i).get("nomUE").toString().equalsIgnoreCase(nomUETemp))
               {
                  nomECUETemp = lesDonnees.get(i).get("nomECUE").toString();
                  noteECUETemp = lesDonnees.get(i).get("saNote").toString();
                  estRattrapage = lesDonnees.get(i).get("estRattrapage").toString();

                  if (!noteECUETemp.equalsIgnoreCase("-1"))
                  {
                     etudiantCourant.ajouterNote(ueCourante.getECUE(nomECUETemp), Float.valueOf(noteECUETemp), yesNo(estRattrapage));
                  }

                  //********* ON BOUCLE *************
                  i++;

               }

            }
         }
         lesEtudiants.add(etudiantCourant);
      }
   }

   /**
    * Fonction qui retourne la liste des étudiants d'une année
    * @param uneAnnee
    * @return Liste d'étudiant
    * @throws Exception : Exception venant des couches inférieures
    */
   public List<Etudiant> getLesEtudiant(Annee uneAnnee) throws Exception
   {
      List<Etudiant> lesEtud = new ArrayList<Etudiant>();

      Iterator iter = lesEtudiants.iterator();
      Etudiant etudCourant = null;

      while (iter.hasNext())
      {
         etudCourant = (Etudiant) iter.next();

         if (etudCourant.getAnnee().compareTo(uneAnnee))
         {
            lesEtud.add(etudCourant);
         }
      }

      return lesEtud;
   }

   /**
    * Fonction qui retourne la liste des étudiants ayant choisi l'UE passé en paramètre
    * @param uneUE
    * @return Liste d'étudiants
    * @throws Exception : Exception venant des couches inférieures
    */
   public List<Etudiant> getLesEtudiantUE(UE uneUE) throws Exception
   {
      List<Etudiant> lesEtud = new ArrayList<Etudiant>();

      Iterator iter = lesEtudiants.iterator();
      Etudiant etudCourant = null;

      while (iter.hasNext())
      {
         etudCourant = (Etudiant) iter.next();

         if (etudCourant.getSesUE().contains(uneUE))
         {
            lesEtud.add(etudCourant);
         }
      }

      return lesEtud;
   }

   /**
    * Fonction qui retourne la liste des étudiants étudiant l'ECUE passé en paramètre
    * @param uneECUE
    * @return Liste d'étudiants
    * @throws Exception : Exception venant des couches inférieures
    */
   public List<Etudiant> getLesEtudiantECUE(ECUE uneECUE) throws Exception
   {
      List<Etudiant> lesEtud = new ArrayList<Etudiant>();
      Iterator iter = lesEtudiants.iterator();
      Etudiant etudCourant = null;

      while (iter.hasNext())
      {
         etudCourant = (Etudiant) iter.next();

         if (etudCourant.getSesECUE().contains(uneECUE))
         {
            lesEtud.add(etudCourant);
         }
      }

      return lesEtud;
   }

   /**
    * Fonction qui retourne la liste des étudiants étudiant le semestre passé en paramètre
    * @param unSemestre
    * @return Liste d'étudiants
    * @throws Exception : Exception venant des couches inférieures
    */
   public List<Etudiant> getLesEtudiantSemestre(Semestre unSemestre) throws Exception
   {
      List<Etudiant> lesEtud = new ArrayList<Etudiant>();
      Iterator iter = lesEtudiants.iterator();
      Etudiant etudCourant = null;

      while (iter.hasNext())
      {
         etudCourant = (Etudiant) iter.next();

         if (etudCourant.getSesSemestres().contains(unSemestre))
         {
            lesEtud.add(etudCourant);
         }
      }

      return lesEtud;
   }

   /**
    * Procédure d'attribution de note pour un étudiant
    * @param unNom : nom de l'étudiant
    * @param unPrenom : prénom de l'étudiant
    * @param uneNote : la note
    * @param estRattrapage : 1 s'il y a eu un rattrapage, 0 sinon
    * @throws Exception : Exception venant des couches inférieures
    */
   public void setNote(String unNom, String unPrenom, ECUE ecue, float uneNote, boolean estRattrapage)
   {
      Etudiant etudCourant = getEtudiant(unNom, unPrenom);
      Notation note = null;
      if (etudCourant != null)
      {
         note = etudCourant.getNoteECUE(ecue);
         if (note != null)
         {
            note.setNote(uneNote);
            note.setIsSecondSession(estRattrapage);
         }
         else
         {
            etudCourant.ajouterNote(ecue, uneNote, estRattrapage);
         }
      }
   }

   /**
    * Procédure d'attribution par décision du jury
    * @param unNom : nom de l'étudiant
    * @param unPrenom : prénom de l'étudiant
    * @param estAPDJ : 1 si c'est un apdj, 0 sinon
    * @throws Exception : Exception venant des couches inférieures
    */
   public void setAPDJ(String unNom, String unPrenom, UE ue, Boolean estAPDJ)
   {
      Etudiant etudCourant = getEtudiant(unNom, unPrenom);

      if (etudCourant != null)
      {
         if (estAPDJ)
         {
            if (!etudCourant.getLesAPDJ().contains(ue))
            {
               etudCourant.ajouterAPDJuE(ue);
            }
         }
         else
         {
            if (etudCourant.getLesAPDJ().contains(ue))
            {
               etudCourant.getLesAPDJ().remove(ue);
               etudCourant.getLesAPDJ().remove(ue);
            }
         }
      }
   }

   /**
    * Procédure d'attribution de points jury année
    * @param unNom : nom de l'étudiant
    * @param unPrenom : prénom de l'étudiant
    * @param nbPoint : nombre de point attribués
    * @throws Exception : Exception venant des couches inférieures
    */
   public void setPointJuryAnnee(String unNom, String unPrenom, Annee annee, Float nbPoint)
   {
      Etudiant etudCourant = getEtudiant(unNom, unPrenom);
      PointJury temp = null;

      if (etudCourant != null)
      {
         temp = etudCourant.getPointJuryAnnee(annee);
         if (temp == null)
         {
            etudCourant.addPointJuryA(annee, nbPoint);
         }
         else
         {
            temp.setNbPointJury(nbPoint);
         }
      }
   }

   /**
    * Procédure d'attribution de points jury semestre
    * @param unNom : nom de l'étudiant
    * @param unPrenom : prénom de l'étudiant
    * @param nbPoint : nombre de point attribués
    * @throws Exception  : Exception venant des couches inférieures
    */
   public void setPointJurySemestre(String unNom, String unPrenom, Semestre semestre, Float nbPoint)
   {
      Etudiant etudCourant = getEtudiant(unNom, unPrenom);
      PointJury temp = null;

      if (etudCourant != null)
      {
         temp = etudCourant.getPointJurySemestre(semestre);
         if (temp == null)
         {
            etudCourant.addPointJuryS(semestre, nbPoint);
         }
         else
         {
            temp.setNbPointJury(nbPoint);
         }
      }
   }

   /**
    * Fonction qui retourne un booléan selon la chaîne de caractère
    * @param test 1 ou 0
    * @return VRAI si test=1 sinon FAUX
    */
   public boolean yesNo(String test)
   {
      if (test.equalsIgnoreCase("1"))
      {
         return true;
      }
      else if (test.equalsIgnoreCase("0"))
      {
         return false;
      }
      else
      {
         return false;
      }
   }

   /**
    * Fonction qui retourne l'étudiant
    * @param unNom
    * @param unPrenom
    * @return Etudiant
    */
   public Etudiant getEtudiant(String unNom, String unPrenom)
   {

      Iterator iter = lesEtudiants.iterator();
      Etudiant etudCourant = null;

      while (iter.hasNext() && !(etudCourant = (Etudiant) iter.next()).compareTo(unNom, unPrenom))
      {
         continue;
      }

      return etudCourant;
   }

   /**
    * Procédure qui enregistre en persistence les notes
    * @throws Exception  : Exception venant des couches inférieures
    */
   public void enregistrerNoteECUE(ECUE ecue) throws Exception
   {
      Iterator iterEtudiants = lesEtudiants.iterator();
      Etudiant etudCourant = null;
      Iterator iterNoation = null;
      Notation noteCourante = null;

      while (iterEtudiants.hasNext())
      {
         etudCourant = (Etudiant) iterEtudiants.next();

         noteCourante = etudCourant.getNoteECUE(ecue);
         if(noteCourante!=null)
         {
            if (service.existeNote(etudCourant.getNom(), etudCourant.getPrenom(), noteCourante.getMatiere().getNom()).equalsIgnoreCase("0"))
            {
               //On insère
               service.insertNote(etudCourant.getNom(), etudCourant.getPrenom(), noteCourante.getMatiere().getNom(), Float.toString(noteCourante.getNote()), trueFalse(noteCourante.isIsSecondSession()));
            }
            else
            {
               //On update
               service.updateNote(etudCourant.getNom(), etudCourant.getPrenom(), noteCourante.getMatiere().getNom(), Float.toString(noteCourante.getNote()), trueFalse(noteCourante.isIsSecondSession()));
            }
         }
      }

   }

   /**
    * Procédure qui enregistre en persistence les APDJ
    * @throws Exception : Exception venant des couches inférieures
    */
   public void enregistrerAPDJ() throws Exception
   {
      Iterator iterEtudiants = lesEtudiants.iterator();
      Etudiant etudCourant = null;
      Iterator iterAPDJ = null;


      while (iterEtudiants.hasNext())
      {
         etudCourant = (Etudiant) iterEtudiants.next();

         service.deleteAllAPDJ(etudCourant.getNom(), etudCourant.getPrenom());

         iterAPDJ = etudCourant.getLesAPDJ().iterator();

         while (iterAPDJ.hasNext())
         {
            UE currentUE = (UE)iterAPDJ.next();
            service.insertAPDJ(etudCourant.getNom(), etudCourant.getPrenom(), (currentUE).getNom());

         }

      }
   }

   /**
    * Procédure qui enregistre en persistence les points jury semestres
    * @throws Exception : Exception venant des couches inférieures
    */
   public void enregistrerJS() throws Exception
   {
      Iterator iterEtudiants = lesEtudiants.iterator();
      Etudiant etudCourant = null;
      Iterator iterPointJury = null;
      PointJury ptCourant = null;


      while (iterEtudiants.hasNext())
      {
         etudCourant = (Etudiant) iterEtudiants.next();

         service.deleteAllPointJurySemestre(etudCourant.getNom(), etudCourant.getPrenom());

         iterPointJury = etudCourant.getPointJury().iterator();

         while (iterPointJury.hasNext())
         {
            ptCourant = ((PointJury) iterPointJury.next());
            if (ptCourant.getAnnee() == null)
            {
               service.insertPointJurySemestre(etudCourant.getNom(), etudCourant.getPrenom(), ptCourant.getLeSemestre().getCodeApogee(), Float.toString(ptCourant.getNbPointJury()));
            }

         }

      }
   }

   /**
    * Procédure qui enregistre en persistence les points jury année
    * @throws Exception : Exception venant des couches inférieures
    */
   public void enregistrerJA() throws Exception
   {
      Iterator iterEtudiants = lesEtudiants.iterator();
      Etudiant etudCourant = null;
      Iterator iterPointJury = null;
      PointJury ptCourant = null;
      while (iterEtudiants.hasNext())
      {
         etudCourant = (Etudiant) iterEtudiants.next();

         service.deleteAllPointJurySemestre(etudCourant.getNom(), etudCourant.getPrenom());

         iterPointJury = etudCourant.getPointJury().iterator();

         while (iterPointJury.hasNext())
         {
            ptCourant = ((PointJury) iterPointJury.next());
            if (ptCourant.getLeSemestre() == null)
            {
               service.insertPointJuryAnnee(etudCourant.getNom(), etudCourant.getPrenom(), Float.toString(ptCourant.getNbPointJury()));
            }

         }

      }
   }

   /**
    * Fonction qui retourne un booléan en chaîne de caractères
    * @param bool
    * @return "1" si bool = VTRAI, "0" sinon
    */
   public String trueFalse(boolean bool)
   {
      if (bool)
      {
         return "1";
      }
      else
      {
         return "0";
      }
   }
}
